package com.ruoyi.web.controller.file;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.file.domain.FileInfo;
import com.ruoyi.file.domain.qo.FileInfoQo;
import com.ruoyi.file.domain.vo.FileInfoVo;
import com.ruoyi.file.service.FileInfoService;
import com.ruoyi.hazard.domain.qo.HazardInfoQo;
import com.ruoyi.hazard.domain.vo.HazardInfoVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

@Api(tags="文件管理")
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController extends BaseController {

    @Resource
    private FileInfoService fileInfoService;

//    @PreAuthorize("@ss.hasPermi('docs:file:list')")
//    @ApiOperation("文件分页列表")
//    @PostMapping("/list")
//    public R<IPage<FileInfo>> listFiles(@Validated @RequestBody FileInfoPageQo file) {
//        try {
//            LambdaQueryWrapper<FileInfo> qw =  fileInfoService.getQueryWrapper(file);
//            IPage<FileInfo> page=fileInfoService.getPage(qw,file.getPageNum() ==null? 1:file.getPageNum(),file.getPageSize() ==null?10:file.getPageSize());
//            return R.ok(page);
//        } catch (Exception e) {
//            log.error("文件列表查询异常：{}", e.getMessage());
//            return R.fail("文件列表查询异常");
//        }
//    }

    @PreAuthorize("@ss.hasPermi('docs:file:list')")
    @ApiOperation("文件分页列表")
    @GetMapping("/list")
    public TableDataInfo listFiles(FileInfoQo file) {
        startPage();
        List<FileInfo> list = fileInfoService.list(fileInfoService.getQueryWrapper(file));
        return getDataTable(list);
//        try {
//            LambdaQueryWrapper<FileInfo> qw =  fileInfoService.getQueryWrapper(file);
//            IPage<FileInfo> page=fileInfoService.getPage(qw,file.getPageNum() ==null? 1:file.getPageNum(),file.getPageSize() ==null?10:file.getPageSize());
//            return R.ok(page);
//        } catch (Exception e) {
//            log.error("文件列表查询异常：{}", e.getMessage());
//            return R.fail("文件列表查询异常");
//        }
    }


    @ApiOperation("下载文件信息模板")
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response)
    {
        ExcelUtil<FileInfo> util = new ExcelUtil<FileInfo>(FileInfo.class);
        util.importTemplateExcel(response, "文件信息");
    }

    @PreAuthorize("@ss.hasPermi('docs:file:export')")
    @PostMapping("/export")
    @ApiOperation("导出文件信息")
    public void export(HttpServletResponse response, FileInfoQo file){
        List<FileInfo> list = fileInfoService.list(fileInfoService.getQueryWrapper(file));
        ExcelUtil<FileInfo> util = new ExcelUtil<FileInfo>(FileInfo.class);
        util.exportExcel(response, list, "文件信息");
    }


    @PreAuthorize("@ss.hasPermi('docs:file:import')")
    @ApiOperation("导入文件信息")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception{
        ExcelUtil<FileInfo> util = new ExcelUtil<FileInfo>(FileInfo.class);
        List<FileInfo> fileInfos = util.importExcel(file.getInputStream());
        String message = fileInfoService.importData(fileInfos, updateSupport);
        return success(message);
    }



    @ApiOperation("文件关键字搜索")
    @GetMapping("/key")
    public R<List<FileInfo>> key(@Validated @RequestBody FileInfoQo file) {
        LambdaQueryWrapper<FileInfo> qw =  fileInfoService.getQueryWrapper(file);
        List<FileInfo> list = fileInfoService.list(qw);
        return R.ok(list);
    }




    @PreAuthorize("@ss.hasPermi('docs:file:add')")
    @PostMapping("/addInfo")
    @ApiOperation("新增文件信息")
    public R<FileInfo> addFileInfo(
            @Validated @RequestBody FileInfoVo fileInfo
    ) {
        try {
            //新增文件信息(本地文件)
            FileInfo myfileInfo = fileInfoService.add(fileInfo.getCode(),fileInfo.getNewFileName(),fileInfo.getBusinessType(),fileInfo.getRemark(),fileInfo.getUrl());
            return R.ok(myfileInfo);
        } catch (Exception e) {
            log.error("新增文件信息：{}", e.getMessage());
            return R.fail("新增文件信息异常");
        }
    }

    @PreAuthorize("@ss.hasPermi('docs:file:add')")
    @PostMapping("/addInfos")
    @ApiOperation("批量新增文件信息")
    public R<List<FileInfo>> addFileInfos(@Validated @RequestBody List<FileInfoVo> fileInfos) {
        try {
            //新增文件信息(本地文件)
            if(CollectionUtils.isEmpty(fileInfos)){
                return R.fail("文件信息不能为空");
            }
            List<FileInfo> list = fileInfos.stream().map(fileInfo -> {
                FileInfo myfileInfo = fileInfoService.add(fileInfo.getCode() ,fileInfo.getNewFileName(),fileInfo.getBusinessType(),fileInfo.getRemark(),fileInfo.getUrl());
                return myfileInfo;
            }).collect(Collectors.toList());
            return R.ok(list);
        } catch (Exception e) {
            log.error("新增文件信息：{}", e.getMessage());
            return R.fail("新增文件信息异常");
        }
    }


    @PreAuthorize("@ss.hasPermi('docs:file:edit')")
    @PutMapping("/updateInfo")
    @ApiOperation("修改文件信息")
    public R<FileInfo> updateInfo(@Validated @RequestBody FileInfo fileInfo){
        try {
            if(fileInfo == null){
                return R.fail("文件信息不能为空");
            }
            if(fileInfo.getId()==null){
                return R.fail("文件信息ID不能为空");
            }
            FileInfo dbFileInfo = fileInfoService.getById(fileInfo.getId());
            if(dbFileInfo == null){
                return R.fail("文件信息不存在");
            }
            fileInfoService.updateById(fileInfo);
            return R.ok(fileInfo);
        } catch (Exception e) {
            log.error("新增文件信息：{}", e.getMessage());
            return R.fail("新增文件信息异常");
        }
    }

//    @PreAuthorize("@ss.hasPermi('docs:file:delete')")
//    @DeleteMapping("/delete/{fileId}")
//    @ApiOperation("删除文件")
//    @ApiImplicitParam(name = "fileId", value = "文件ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
//    @ApiResponses(value = {
//            @ApiResponse(code = 200, message = "文件删除成功", response = R.class),
//            @ApiResponse(code = 400, message = "请求参数错误", response = R.class),
//            @ApiResponse(code = 500, message = "服务器内部错误", response = R.class)
//    })
//    public R delete(@PathVariable Long fileId) {
//        try {
//            FileInfo dbFileInfo = fileInfoService.getById(fileId);
//            if(dbFileInfo == null){
//                return R.fail("文件信息不存在");
//            }
//            //fileInfoService.deleteFile(fileId);
//            fileInfoService.removeById(fileId);
//            return R.ok("文件删除成功");
//        } catch (Exception e) {
//            log.error("文件删除异常：{}", e.getMessage());
//            return R.fail("文件删除异常："+e.getMessage());
//        }
//    }


    @PreAuthorize("@ss.hasPermi('docs:file:delete')")
    @PostMapping("/delete")
    @ApiOperation("批量删除文件")
    @ApiImplicitParam(name = "fileIds", value = "文件ID集合", required = true, dataType = "List<Long>", paramType = "body", dataTypeClass = List.class)
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "文件删除成功", response = R.class),
            @ApiResponse(code = 400, message = "请求参数错误", response = R.class),
            @ApiResponse(code = 500, message = "服务器内部错误", response = R.class)
    })
    public R delete(@RequestBody List<Long> fileIds) {
        try {
            if (fileIds == null || fileIds.isEmpty()) {
                return R.fail("文件ID列表不能为空");
            }

            // 检查所有文件是否存在
            List<FileInfo> dbFileInfos = fileInfoService.listByIds(fileIds);
            if (dbFileInfos.size() != fileIds.size()) {
                return R.fail("部分文件不存在");
            }

            // 执行批量删除
            fileInfoService.removeByIds(fileIds);
            return R.ok("文件删除成功");
        } catch (Exception e) {
            log.error("文件删除异常", e);
            return R.fail("文件删除异常：" + e.getMessage());
        }
    }




//    @PreAuthorize("@ss.hasPermi('file:upload')")
//    @PostMapping("/upload")
//    @ApiOperation("文件上传接口")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "file", value = "文件", dataType = "MultipartFile", dataTypeClass = MultipartFile.class),
//            @ApiImplicitParam(name = "businessType", value = "业务类型", dataType = "String", dataTypeClass = String.class),
//            @ApiImplicitParam(name = "remark", value = "备注信息", dataType = "String", dataTypeClass = String.class)
//    })
//    public R<FileInfo> uploadFile(
//            @RequestParam("file") MultipartFile file,
//            @RequestParam(value = "businessType", required = false) String businessType,
//            @RequestParam(value = "remark", required = false) String remark
//            ) {
//        try {
//            FileInfo fileInfo = fileInfoService.uploadFile(file, businessType,remark);
//            return R.ok(fileInfo);
//        } catch (Exception e) {
//            log.error("文件上传异常：{}", e.getMessage());
//            return R.fail("文件上传接口异常");
//        }
//    }

//    @PreAuthorize("@ss.hasPermi('file:upload')")
//    @PostMapping("/upload/batch")
//    @ApiOperation("批量文件上传接口")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "files", value = "文件", dataType = "MultipartFile[]", dataTypeClass = MultipartFile[].class),
//            @ApiImplicitParam(name = "businessType", value = "业务类型", dataType = "String", dataTypeClass = String.class),
//            @ApiImplicitParam(name = "remark", value = "备注信息", dataType = "String", dataTypeClass = String.class)})
//    public R<List<FileInfo>> uploadFiles(
//            @RequestParam("files") MultipartFile[] files,
//            @RequestParam(value = "businessType", required = false) String businessType,
//            @RequestParam(value = "remark", required = false) String remark) {
//        try {
//            if (CollectionUtils.isEmpty(Arrays.asList(files))) {
//                return R.fail("请选择要上传的文件");
//            }
//            List<FileInfo> fileInfos = fileInfoService.uploadFiles(files, businessType,remark);
//            return R.ok(fileInfos);
//        } catch (Exception e) {
//            log.error("文件上传异常：{}", e.getMessage());
//            return R.fail("文件上传接口异常");
//        }
//    }








//    @GetMapping("/download/{fileId}")
//    @ApiOperation("文件下载")
//    @ApiImplicitParam(name = "fileId", value = "文件ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class)
//    public ResponseEntity<StreamingResponseBody> downloadFile(@PathVariable Long fileId) {
//        try {
//            FileInfo fileInfo = fileInfoService.getById(fileId);
//            if(fileInfo == null){
//                log.error("文件下载：{} 对应的信息未找到", fileId);
//                throw new ServiceException("对应的文件信息未找到");
//            }
//            InputStream inputStream = fileInfoService.downloadFile(fileInfo);
//            StreamingResponseBody responseBody = outputStream -> {
//                byte[] buffer = new byte[8192];
//                int bytesRead;
//                while ((bytesRead = inputStream.read(buffer)) != -1) {
//                    outputStream.write(buffer, 0, bytesRead);
//                }
//                inputStream.close(); // 手动关闭输入流
//            };
//            // 使用RFC 5987标准编码文件名
//            String encodedFilename = URLEncoder.encode(fileInfo.getFileName(), StandardCharsets.UTF_8.name());
//            String contentDisposition = "attachment; filename*=UTF-8''" + encodedFilename;
//            return ResponseEntity.ok()
//                    .header(HttpHeaders.CONTENT_DISPOSITION,
//                            contentDisposition)
//                    .contentType(MediaType.parseMediaType(fileInfo.getFileType()))
//                    .contentLength(fileInfo.getFileSize())
//                    .body(responseBody);
//        } catch (Exception e) {
//            log.error("文件下载异常：{}", e.getMessage());
//            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
//        }
//    }

//    @PostMapping("/download/batch")
//    @ApiOperation("批量文件下载")
//    @ApiImplicitParam(name = "fileIds", value = "文件ID列表", required = true, dataType = "List<Long>", paramType = "body", dataTypeClass = List.class)
//    public ResponseEntity<StreamingResponseBody> downloadFiles(@RequestBody List<Long> fileIds) {
//        try {
//            if(CollectionUtils.isEmpty(fileIds)){
//                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
//            }
//            List<FileInfo> fileInfos = fileInfoService.getByIds(fileIds);
//            if(CollectionUtils.isEmpty(fileInfos)){
//                return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
//            }
//            StreamingResponseBody responseBody = outputStream -> {
//                try (ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream)) {
//                    byte[] buffer = new byte[8192];
//
//                    for (FileInfo fileInfo : fileInfos) {
//                        try (InputStream inputStream = fileInfoService.downloadFile(fileInfo)) {
//                            // 创建zip条目，使用文件名作为条目名称
//                            ZipEntry zipEntry = new ZipEntry(fileInfo.getFileName());
//                            zipOutputStream.putNextEntry(zipEntry);
//
//                            // 将文件内容写入zip输出流
//                            int bytesRead;
//                            while ((bytesRead = inputStream.read(buffer)) != -1) {
//                                zipOutputStream.write(buffer, 0, bytesRead);
//                            }
//
//                            zipOutputStream.closeEntry();
//                        } catch (Exception e) {
//                            log.error("打包文件时发生异常，文件ID: {}，文件名: {}", fileInfo.getId(), fileInfo.getFileName(), e);
//                            // 继续处理其他文件
//                        }
//                    }
//                } catch (IOException e) {
//                    log.error("创建ZIP文件时发生异常", e);
//                    throw new ServiceException("文件打包失败");
//                }
//            };
//
//            String encodedFilename = URLEncoder.encode("files.zip", StandardCharsets.UTF_8.name());
//            String contentDisposition = "attachment; filename*=UTF-8''" + encodedFilename;
//
//            return ResponseEntity.ok()
//                    .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
//                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
//                    .body(responseBody);
//
//        }catch (Exception e) {
//            log.error("文件下载异常：{}", e.getMessage());
//            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
//        }
//    }
//
//
//    @GetMapping("/stream/{fileId}")
//    @ApiOperation("视频文件流")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "fileId", value = "文件ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class),
//            @ApiImplicitParam(name = "Range", value = "范围请求头", required = false, dataType = "String", paramType = "header", dataTypeClass = String.class)})
//    public ResponseEntity<InputStreamResource> streamVideo( @PathVariable Long fileId,
//                                                            @RequestHeader(value = "Range", required = false) String rangeHeader){
//        FileInfo fileInfo = fileInfoService.getById(fileId);
//        if(fileInfo == null){
//            log.error("文件下载：{} 对应的信息未找到", fileId);
//            throw new ServiceException("对应的文件信息未找到");
//        }
//        // 获取视频流
//        try {
//            GetObjectResponse object = fileInfoService.downloadObject(fileInfo);
//            // 判断是否支持范围请求（用于进度条拖动）
//            boolean isRangeSupported = rangeHeader != null && rangeHeader.startsWith("bytes=");
//            // 设置响应头
//            HttpHeaders headers = new HttpHeaders();
//            headers.setContentType(MediaType.parseMediaType(fileInfo.getFileType()));
//            headers.set("Accept-Ranges", "bytes");
//
//            if (isRangeSupported) {
//                // 处理范围请求（部分内容）
//                return handleRangeRequest(object, fileInfo, rangeHeader, headers);
//            } else {
//                // 完整视频流
//                headers.setContentLength(fileInfo.getFileSize());
//                return new ResponseEntity<>(
//                        new InputStreamResource(object),
//                        headers,
//                        HttpStatus.OK);
//            }
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }
//
//    }

//    /**
//     * 处理范围请求（支持视频进度条拖动）
//     */
//    private ResponseEntity<InputStreamResource> handleRangeRequest(
//            GetObjectResponse object,
//            FileInfo fileInfo,
//            String rangeHeader,
//            HttpHeaders headers) throws IOException {
//
//        long fileSize = fileInfo.getFileSize();
//        String[] ranges = rangeHeader.substring(6).split("-");
//        long rangeStart = Long.parseLong(ranges[0]);
//        long rangeEnd = ranges.length > 1 ? Long.parseLong(ranges[1]) : fileSize - 1;
//
//        // 确保范围有效
//        if (rangeEnd >= fileSize) {
//            rangeEnd = fileSize - 1;
//        }
//
//        long contentLength = rangeEnd - rangeStart + 1;
//
//        // 设置部分内容响应头
//        headers.set("Content-Range", "bytes " + rangeStart + "-" + rangeEnd + "/" + fileSize);
//        headers.setContentLength(contentLength);
//
//        // 跳过不需要的部分
//        object.skip(rangeStart);
//
//        return new ResponseEntity<>(
//                new InputStreamResource(object),
//                headers,
//                HttpStatus.PARTIAL_CONTENT);
//    }

}
